package com.david.mydemo.ctl_email;

import java.io.File;
import java.io.StringWriter;
import java.util.Date;
import java.util.Properties;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Address;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;

import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.app.VelocityEngine;

/**
 * 邮件发送器
 */
public class MailSendUtils {

	/**
	 * 邮箱发送，用模板设置内容
	 */
	public static void sendTemplateEmail(String email, String userName) {
		// 发送邮件类型
		String type = "2";
		// 发送到邮箱地址
		String toEmail = email;
		// 邮件标题
		String title = "喜中大奖";
		// 邮件内容
		String content = "测试邮箱发送接口，Hello！";
		// 附件
		// String[] files = { "D:\\123.txt" };

		// 模板名称
		String templateName = "template.vm";
		// 模板填充内容
		VelocityContext ctx = new VelocityContext();
		ctx.put("userName", userName);
		ctx.put("url", "https://www.baidu.com/");
		ctx.put("title", title);
		// 根据模板和内容生成邮件内容，如果不需要模板就直接发送contents
		try {
			content = MailSendUtils.getMailContent(templateName, ctx);
		} catch (Exception e) {
			e.printStackTrace();
		}

		// 发送邮件
		MailSendUtils.sendEmail(type, toEmail, title, content, null);
	}

	/**
	 * 发送邮件接口
	 *
	 * @param type
	 *            1：文本格式;2：HTML格式,
	 * @param toEmail
	 *            对方箱账号
	 * @param title
	 *            标题
	 * @param content
	 *            内容
	 * @param files
	 *            附件地址
	 */
	public static boolean sendEmail(String type, String toEmail, String title, String content, String[] files) {
		// 设置邮件信息
		MailBody mailInfo = new MailBody();
		mailInfo.setValidate(true);
		mailInfo.setToAddress(toEmail);
		mailInfo.setSubject(title);
		mailInfo.setContent(content);
		mailInfo.setAttachFileNames(files);

		// 这个类主要来发送邮件
		MailSendUtils sms = new MailSendUtils();
		try {
			if ("1".equals(type)) {
				return sms.sendTextMail(mailInfo);
			} else {
				return sms.sendHtmlMail(mailInfo);
			}
		} catch (Exception e) {
			System.out.println("邮件发送测试，失败！！！");
			e.printStackTrace();
			return false;
		}
	}

	/**
	 * 以文本格式发送邮件
	 *
	 * @param mailInfo
	 *            待发送的邮件的信息
	 */
	public boolean sendTextMail(MailBody mailInfo) throws Exception {
		// 判断是否需要身份认证
		MailAuthenticator authenticator = null;
		Properties pro = mailInfo.getProperties();
		if (mailInfo.isValidate()) {
			// 如果需要身份认证，则创建一个密码验证器
			authenticator = new MailAuthenticator(mailInfo.getUserName(), mailInfo.getPassword());
		}
		// 根据邮件会话属性和密码验证器构造一个发送邮件的session
		Session sendMailSession = Session.getDefaultInstance(pro, authenticator);
		// logBefore(logger, "构造一个发送邮件的session");

		// 根据session创建一个邮件消息
		Message mailMessage = new MimeMessage(sendMailSession);
		// 防止成为垃圾邮件，披上outlook的马甲
		mailMessage.addHeader("X-Priority", "3");
		mailMessage.addHeader("X-MSMail-Priority", "Normal");
		mailMessage.addHeader("X-Mailer", "Microsoft Outlook Express 6.00.2900.2869");
		mailMessage.addHeader("X-MimeOLE", "Produced By Microsoft MimeOLE V6.00.2900.2869");
		mailMessage.addHeader("ReturnReceipt", "1");
		// 创建邮件发送者地址
		Address from = new InternetAddress(mailInfo.getFromAddress());
		// 设置邮件消息的发送者
		mailMessage.setFrom(from);
		// 创建邮件的接收者地址，并设置到邮件消息中
		Address to = new InternetAddress(mailInfo.getToAddress());
		mailMessage.setRecipient(Message.RecipientType.TO, to);
		// 设置邮件消息的主题
		mailMessage.setSubject(mailInfo.getSubject());
		// 设置邮件消息发送的时间
		mailMessage.setSentDate(new Date());
		// 设置邮件消息的主要内容
		String mailContent = mailInfo.getContent();
		mailMessage.setText(mailContent);
		// 发送邮件
		Transport.send(mailMessage);
		System.out.println("邮件发送测试，成功！");
		return true;
	}

	/**
	 * 以HTML格式发送邮件
	 *
	 * @param mailInfo
	 *            待发送的邮件信息
	 */
	public boolean sendHtmlMail(MailBody mailInfo) throws Exception {
		// 判断是否需要身份认证
		MailAuthenticator authenticator = null;
		Properties pro = mailInfo.getProperties();
		// 如果需要身份认证，则创建一个密码验证器
		if (mailInfo.isValidate()) {
			authenticator = new MailAuthenticator(mailInfo.getUserName(), mailInfo.getPassword());
		}
		// 根据邮件会话属性和密码验证器构造一个发送邮件的session
		Session sendMailSession = Session.getDefaultInstance(pro, authenticator);
		// 设置session的调试模式，发布时取消
		// sendMailSession.setDebug(true);

		// 根据session创建一个邮件消息
		Message mailMessage = new MimeMessage(sendMailSession);
		// 防止成为垃圾邮件，披上outlook的马甲
		mailMessage.addHeader("X-Priority", "3");
		mailMessage.addHeader("X-MSMail-Priority", "Normal");
		mailMessage.addHeader("X-Mailer", "Microsoft Outlook Express 6.00.2900.2869");
		mailMessage.addHeader("X-MimeOLE", "Produced By Microsoft MimeOLE V6.00.2900.2869");
		mailMessage.addHeader("ReturnReceipt", "1");
		// 创建邮件发送者地址
		Address from = new InternetAddress(mailInfo.getFromAddress());
		// 设置邮件消息的发送者
		mailMessage.setFrom(from);
		// 创建邮件的接收者地址，并设置到邮件消息中
		Address to = new InternetAddress(mailInfo.getToAddress());
		// Message.RecipientType.TO属性表示接收者的类型为TO
		mailMessage.setRecipient(Message.RecipientType.TO, to);
		// 设置邮件消息的主题
		mailMessage.setSubject(mailInfo.getSubject());
		// 设置邮件消息发送的时间
		mailMessage.setSentDate(new Date());
		// MiniMultipart类是一个容器类，包含MimeBodyPart类型的对象
		Multipart mainPart = new MimeMultipart();
		// 判断是否存在附件
		if (mailInfo.getAttachFileNames() != null) {
			for (String fileName : mailInfo.getAttachFileNames()) {
				// 创建一个包含附件内容的MimeBodyPart
				MimeBodyPart file = new MimeBodyPart();
				// 数据处理器
				DataHandler dataHandler = new DataHandler(new FileDataSource(fileName));
				// 设置附件数据
				file.setDataHandler(dataHandler);
				// 设置附件名称
				file.setFileName(MimeUtility.encodeText(dataHandler.getName()));
				mainPart.addBodyPart(file);
			}
		}
		// 创建一个包含HTML内容的MimeBodyPart
		MimeBodyPart html = new MimeBodyPart();
		// 设置HTML内容
		html.setContent(mailInfo.getContent(), "text/html; charset=utf-8");
		mainPart.addBodyPart(html);
		// 将MiniMultipart对象设置为邮件内容
		mailMessage.setContent(mainPart);
		// 发送邮件
		Transport.send(mailMessage);
		System.out.println("邮件发送测试，成功！");
		return true;
	}

	/**
	 * 生成模板内容
	 *
	 * @param templateName
	 *            模板名称
	 * @param velocityContext
	 *            填充模板内容
	 * @return 合并模板内容
	 */
	public static String getMailContent(String templateName, VelocityContext velocityContext) throws Exception {
		// 从配置文件中获取模板路径
		String templatePath = "\\template\\vm";
		StringWriter stringWriter = new StringWriter();
		// velocity引擎
		VelocityEngine velocityEngine = new VelocityEngine();
		// 设置文件路径属性
		Properties properties = new Properties();
		// 通过类加载器获取模板文件夹路径
		String path = MailSendUtils.class.getResource("/").getPath();
//		String templateFolder = new File(path).getParentFile().getParentFile().getCanonicalPath() + templatePath;
		String templateFolder = "d:\\template";

		// 设置模板文件夹路径
		properties.setProperty(Velocity.FILE_RESOURCE_LOADER_PATH, templateFolder);
		// 设置输入输出编码类型
		properties.setProperty(Velocity.ENCODING_DEFAULT, "utf-8");
		properties.setProperty(Velocity.INPUT_ENCODING, "utf-8");
		properties.setProperty(Velocity.OUTPUT_ENCODING, "utf-8");
		properties.setProperty("runtime.log.logsystem.class", "org.apache.velocity.runtime.log.SimpleLog4JLogSystem");
		properties.setProperty("runtime.log.logsystem.log4j.category", "velocity");
		properties.setProperty("runtime.log.logsystem.log4j.logger", "velocity");
		// 引擎初始化属性配置
		velocityEngine.init(properties);
		// 加载指定模版
		Template template = velocityEngine.getTemplate(templateName, "utf-8");
		// 写到模板
		template.merge(velocityContext, stringWriter);
		return stringWriter.toString();
	}

}
